home *** CD-ROM | disk | FTP | other *** search
/ Aminet 15 / Aminet 15 - Nov 1996.iso / Aminet / util / misc / ClockFreq.lha / Source / CiaTimer.mod < prev    next >
Encoding:
Modula Implementation  |  1996-08-17  |  5.3 KB  |  218 lines

  1. (* Converted from C-Example in RKM-Companion 2.04 *)
  2.  
  3. IMPLEMENTATION MODULE CiaTimer;
  4.  
  5. IMPORT Arts;
  6. IMPORT CR: Resources;
  7. IMPORT HW: Hardware;
  8. IMPORT ED: ExecD;
  9. IMPORT EL: ExecL;
  10. IMPORT R;
  11. FROM SYSTEM IMPORT ADDRESS, ADR, CAST, ASSEMBLE;
  12.  
  13. (*$ EntryClear:= FALSE
  14.     NilChk:= FALSE
  15.     StackChk:= FALSE
  16.     RangeChk:= FALSE
  17.     OverflowChk:= FALSE
  18. *)
  19.  
  20.  
  21.  
  22. TYPE
  23.    FreeTimer= RECORD
  24.       ciaBase: ED.LibraryPtr;
  25.       timerBit: HW.CiaIcrFlags;
  26.       ciaP: POINTER TO HW.CIAA;
  27.       stopMask: HW.CiaCraFlagSet;
  28.       startMask: HW.CiaCraFlagSet;
  29.       ciaCr: POINTER TO HW.CiaCraFlagSet;
  30.       ciaHi: POINTER TO SHORTCARD;
  31.       ciaLo: POINTER TO SHORTCARD;
  32.       oldAbleMask: HW.CiaIcrFlagSet;
  33.       gotIt: BOOLEAN;
  34.    END;
  35.  
  36.  
  37. VAR
  38.    FreeT: FreeTimer;
  39.    StopCounter: CARDINAL;
  40.  
  41.  
  42. (* Start- and StopTimer are coded in assembler to make them as
  43.    small as possible, because they should not use much cache space *)
  44. (*$EntryExitCode:= FALSE*)
  45. (*$LoadA4:= TRUE*)
  46. PROCEDURE CiaStartTimer;
  47. (*VAR
  48.    a2{R.A0}: ADDRESS;
  49.    a4{R.D0}: ADDRESS;*)
  50. BEGIN
  51.    (* Partly setup is done in TryTimer, contrary to C-Example *)
  52.    (*EL.Disable;*)
  53.    (*FreeT.ciaCr^:= FreeT.ciaCr^ * FreeT.stopMask;*)
  54.    ASSEMBLE(MOVE.B FreeT.stopMask(A4), D0
  55.             MOVE.L FreeT.ciaCr(A4), A1
  56.             AND.B   D0, (A1)
  57.             END);
  58.    (*EL.Enable;*)
  59.    (*FreeT.ciaLo^:= 255;
  60.    FreeT.ciaHi^:= 255;*)
  61.    ASSEMBLE(MOVE.L FreeT.ciaLo(A4), A0
  62.             MOVE.B #255, (A0)
  63.             MOVE.L FreeT.ciaHi(A4), A0
  64.             MOVE.B #255, (A0)
  65.             END);
  66. (*   FreeT.ciaCr^:= FreeT.ciaCr^ + FreeT.startMask;*)
  67.    ASSEMBLE(MOVE.B FreeT.startMask(A4), D0
  68.             (*MOVE.L FreeT.ciaCr(A4), A0*)
  69.             OR.B   D0, (A1)
  70.             RTS
  71.             END);
  72.  
  73. END CiaStartTimer;
  74.  
  75.  
  76.  
  77. (*$EntryExitCode:= FALSE*)
  78. (*$LoadA4:= TRUE*)
  79. PROCEDURE CiaStopTimer;
  80. (*VAR
  81.    a1{R.D0}: LONGCARD;
  82.    a2{R.A0}: ADDRESS;
  83.    a3{R.D1}: LONGCARD;*)
  84. BEGIN
  85.  
  86.    ASSEMBLE(MOVE.B FreeT.stopMask(A4), D0
  87.             MOVE.L FreeT.ciaCr(A4), A0
  88.             AND.B   D0, (A0)
  89.             END);
  90.    (*EL.Disable;*)
  91.    (*FreeT.ciaCr^:= FreeT.ciaCr^ * FreeT.stopMask;*)
  92.    (*EL.Enable;*)
  93.    ASSEMBLE(MOVE.L FreeT.ciaHi(A4), A0
  94.             MOVEQ  #0, D0
  95.             MOVE.B (A0), D0
  96.             MOVE.L #256, D1
  97.             MULU.W D0, D1
  98.             MOVE.L FreeT.ciaLo(A4), A0
  99.             MOVE.B (A0), D0
  100.             ADD.W  D0, D1
  101.             MOVE.W D1, StopCounter(A4)
  102.             RTS
  103.             END);
  104.    (*StopCounter:= CARDINAL(FreeT.ciaHi^)*256 + CARDINAL(FreeT.ciaLo^);*)
  105. END CiaStopTimer;
  106.  
  107.  
  108. PROCEDURE CiaGetDiff(): LONGINT;
  109. BEGIN
  110.    RETURN LONGINT(65535-StopCounter);
  111. END CiaGetDiff;
  112.  
  113.  
  114.  
  115. (*
  116.  * Try to obtain a free interval timer on a CIA.
  117.  *)
  118. PROCEDURE TryTimer(VAR Ft: FreeTimer): BOOLEAN;
  119. BEGIN
  120.    EL.Disable;
  121.  
  122.    IF NIL = CR.AddICRVector(Ft.ciaBase, HW.ta, NIL) THEN
  123.       Ft.timerBit:= HW.ta;
  124.       Ft.oldAbleMask:= CR.AbleICR(Ft.ciaBase, HW.CiaIcrFlagSet{HW.ta});
  125.       Ft.ciaCr:= ADR(Ft.ciaP^.cra);
  126.       Ft.ciaHi:= ADR(Ft.ciaP^.tahi);
  127.       Ft.ciaLo:= ADR(Ft.ciaP^.talo);
  128.       Ft.startMask:= HW.CiaCraFlagSet{HW.craStart, HW.craRunmode};
  129.       Ft.stopMask:= HW.CiaCraFlagSet{HW.craTodin, HW.craSpmode, HW.craRunmode, HW.craOutmode, HW.craPbon};
  130.  
  131.    ELSIF NIL = CR.AddICRVector(Ft.ciaBase, HW.tb, NIL) THEN
  132.       Ft.timerBit:= HW.tb;
  133.       Ft.oldAbleMask:= CR.AbleICR(Ft.ciaBase, HW.CiaIcrFlagSet{HW.tb});
  134.       Ft.ciaCr:= ADR(Ft.ciaP^.crb);
  135.       Ft.ciaHi:= ADR(Ft.ciaP^.tbhi);
  136.       Ft.ciaLo:= ADR(Ft.ciaP^.talo);
  137.       Ft.startMask:= CAST(HW.CiaCraFlagSet, HW.CiaCrbFlagSet{HW.crbStart, HW.crbRunmode});
  138.       Ft.stopMask:= CAST(HW.CiaCraFlagSet, HW.CiaCrbFlagSet{HW.crbAlarm, HW.crbRunmode, HW.crbOutmode, HW.crbPbon});
  139.  
  140.    ELSE
  141.       EL.Enable;
  142.       RETURN FALSE;
  143.    END;
  144.  
  145.    EL.Enable;
  146.    RETURN TRUE;
  147. END TryTimer;
  148.  
  149.  
  150. (*
  151.  * A routine to find a free interval timer.
  152.  *
  153.  * This routine makes no assumptions about which interval timers
  154.  * (if any) are available for use.  Currently there are two interval
  155.  * timers per CIA chip.
  156.  *
  157.  * Because CIA usage may change in the future, your code should use
  158.  * a routine like this to find a free interval timer.
  159.  *
  160.  * Note that the routine takes a preference flag (which is used to
  161.  * to indicate that you would prefer an interval timer on CIA-A).
  162.  * If the flag is FALSE, it means that you would prefer an interval
  163.  * timer on CIA-B.
  164.  *
  165.  *)
  166. PROCEDURE FindFreeTimer(VAR Ft: FreeTimer; PreferA: BOOLEAN): BOOLEAN;
  167. VAR
  168.    CiaABase, CiaBBase: ADDRESS;
  169. BEGIN
  170.    CiaABase:= EL.OpenResource(ADR(CR.ciaaName));
  171.    CiaBBase:= EL.OpenResource(ADR(CR.ciabName));
  172.  
  173.    IF (CiaABase = NIL) OR (CiaBBase = NIL) THEN
  174.       RETURN FALSE;
  175.    END;
  176.  
  177.    IF PreferA THEN
  178.       Ft.ciaBase:= CiaABase;
  179.       Ft.ciaP:= ADR(HW.ciaa);
  180.    ELSE
  181.       Ft.ciaBase:= CiaBBase;
  182.       Ft.ciaP:= ADR(HW.ciab);
  183.    END;
  184.    IF TryTimer(Ft) THEN   RETURN TRUE;   END;
  185.  
  186.    IF ~PreferA THEN
  187.       Ft.ciaBase:= CiaABase;
  188.       Ft.ciaP:= ADR(HW.ciaa);
  189.    ELSE
  190.       Ft.ciaBase:= CiaBBase;
  191.       Ft.ciaP:= ADR(HW.ciab);
  192.    END;
  193.    IF TryTimer(Ft) THEN   RETURN TRUE;   END;
  194.  
  195.    RETURN FALSE;
  196.  
  197. END FindFreeTimer;
  198.  
  199.  
  200.  
  201.  
  202.  
  203. BEGIN
  204.     IF FindFreeTimer(FreeT,TRUE) THEN
  205.        FreeT.gotIt:= TRUE;
  206.     ELSE
  207.        Arts.Assert(TRUE, ADR("Could not allocate CIA-Timer."));
  208.        FreeT.gotIt:= FALSE;
  209.     END;
  210.  
  211.  
  212. CLOSE
  213.    IF FreeT.gotIt THEN
  214.       FreeT.gotIt:= FALSE;
  215.       CR.RemICRVector(FreeT.ciaBase,FreeT.timerBit,NIL);
  216.    END;
  217. END CiaTimer.
  218.